package com.example.sfm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.sfm.exception.ObjectException;
import com.example.sfm.pojo.dto.ClassesDto;
import com.example.sfm.pojo.dto.ClassesQueryDto;
import com.example.sfm.pojo.entity.Classes;
import com.example.sfm.mapper.ClassesMapper;
import com.example.sfm.pojo.entity.Teachers;
import com.example.sfm.pojo.vo.ClassesVo;
import com.example.sfm.result.PageResult;
import com.example.sfm.service.IClassesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.sfm.service.ITeachersService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author sfm
 * @since 2025-03-09
 */
@Service
@RequiredArgsConstructor
public class ClassesServiceImpl extends ServiceImpl<ClassesMapper, Classes> implements IClassesService {

    private final ITeachersService teachersService;

    @Override
    public void createClass(ClassesDto classesDto) {
        Classes classes = BeanUtil.copyProperties(classesDto, Classes.class);
        if (!save(classes)) {
            throw new ObjectException("创建班级失败！");
        }
    }

    @Override
    public PageResult<ClassesVo> listClasses(Page<Classes> page, @NotNull ClassesQueryDto queryDto) {

        LambdaQueryWrapper<Classes> queryWrapper = buildQueryWrapper(queryDto);


        Page<Classes> resultPage = page(page, queryWrapper);


        if (resultPage.getRecords().isEmpty()) {
            return new PageResult<>(0L, Collections.emptyList());
        }


        Map<Integer, String> teacherNameMap = getTeacherNameMap(resultPage.getRecords());


        List<ClassesVo> voList = convertToVoList(resultPage.getRecords(), teacherNameMap);

        return new PageResult<>(resultPage.getTotal(), voList);
    }

    /**
     * 构建动态查询条件
     */
    private LambdaQueryWrapper<Classes> buildQueryWrapper(@NotNull ClassesQueryDto queryDto) {
        return new LambdaQueryWrapper<Classes>()
                .like(StringUtils.isNotBlank(queryDto.getClassName()),
                        Classes::getClassName, queryDto.getClassName())
                .like(StringUtils.isNotBlank(queryDto.getDepartment()),
                        Classes::getDepartment, queryDto.getDepartment())
                .eq(queryDto.getTeacherId() != null,
                        Classes::getTeacherId, queryDto.getTeacherId())
                .eq(queryDto.getGradeYear() != null,
                        Classes::getGradeYear, queryDto.getGradeYear());
    }

    /**
     * 批量获取教师姓名映射
     */
    private Map<Integer, String> getTeacherNameMap(@NotNull List<Classes> classesList) {
        Set<Integer> teacherIds = classesList.stream()
                .map(Classes::getTeacherId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        if (teacherIds.isEmpty()) {
            return Collections.emptyMap();
        }

        return teachersService.listByIds(teacherIds)
                .stream()
                .collect(Collectors.toMap(
                        Teachers::getId,
                        teacher -> StringUtils.defaultIfBlank(teacher.getTeacherName(), "未知教师"),
                        (existing, replacement) -> existing));
    }

    /**
     * 转换VO对象
     */
    private List<ClassesVo> convertToVoList(List<Classes> classesList,
                                            Map<Integer, String> teacherNameMap) {
        return classesList.stream()
                .map(clazz -> {
                    ClassesVo vo = BeanUtil.copyProperties(clazz, ClassesVo.class);
                    vo.setTeacherName(teacherNameMap.getOrDefault(clazz.getTeacherId(), "未知教师"));
                    return vo;
                })
                .toList();
    }

    @Override
    public void updateClass(Integer id, ClassesDto classesDto) {
        Classes classes = getById(id);
        if (classes == null) {
            throw new ObjectException("班级不存在！");
        }
        BeanUtil.copyProperties(classesDto, classes);
        if (!updateById(classes)) {
            throw new ObjectException("更新班级失败！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteClasses(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new ObjectException("班级ID列表不能为空！");
        }
        List<Integer> distinctIds = ids.stream().distinct().toList();
        if (!removeBatchByIds(distinctIds)) {
            throw new ObjectException("删除班级失败！");
        }
    }
}
